/*
 * @Description: 
 * @Author: Junhuang
 * @Date: 2022-02-15 13:49:18
 * @LastEditTime: 2022-03-03 20:31:53
 * @LastEditors: Junhuang
 * @Reference: 
 */

'use strict';

const Controller = require('egg').Controller;
const fs = require('fs');
const path = require('path');
// 异步二进制写入流
const awaitWriteStream = require('await-stream-ready').write;
// 管道读入一个虫洞
const sendToWormhole = require('stream-wormhole');
const dayjs = require('dayjs');
const await = require('await-stream-ready/lib/await');

class FileController extends Controller {
  async upload() {
    const { ctx, app } = this;

    const stream = await this.ctx.getFileStream();
    // 基础的目录
    const uploadBasePath = 'app/public/uploads';
    // 生成文件名
    const filename = `${Date.now()}${Number.parseInt(
      Math.random() * 1000,
    )}${path.extname(stream.filename).toLocaleLowerCase()}`;
    // 生成文件夹
    const dirname = dayjs(Date.now()).format('YYYY/MM/DD');
    function mkdirsSync(dirname) {
      if (fs.existsSync(dirname)) {
        return true;
      }
      else {
        // path.dirname(filepath) 表示获得该文件地址的目录；
        // 例如：filepath = app/public/uploads/2022/02/15 则path.filepath = app/public/uploads/2022/02
        if (mkdirsSync(path.dirname(dirname))) {
          fs.mkdirSync(dirname)
          return true;
        }
      }
    }
    mkdirsSync(path.join(uploadBasePath, dirname));
    // 生成写入路径
    const target = path.join(uploadBasePath, dirname, filename);
    // 写入流
    const writeStream = fs.createWriteStream(target);
    try {
      //异步把文件流 写入
      await awaitWriteStream(stream.pipe(writeStream));
    } catch (err) {
      //如果出现错误，关闭管道
      await sendToWormhole(stream);
      this.ctx.throw(500, err);
    }

    const { protocol } = this.ctx.request;
    let url = path.join('/public/uploads', dirname, filename).replace(/\\|\//g, '/');
    //在数据库中仅存储相对路径，主机地址则在页面段进行配置
    //url = protocol + '://' + this.app.config.webUrl + url;

    ctx.apiSuccesss({ url });
  }
}

module.exports = FileController;
